use async_graphql::*;
use redis::aio::MultiplexedConnection;
use sea_orm::{DatabaseConnection};
use serde::{Deserialize, Serialize};
use crate::entity::product_advertising::Model;
use crate::handler::product_ad_handler::{create_advertising, delete_advertising, get_advertising_list};
use crate::graphql::AuthGuard;

#[derive(Debug, Clone, Serialize, Deserialize, SimpleObject)]
pub struct ProductADObject {
    pub id: String,
    pub product_id: String,
    pub cover_addr: String,
    pub create_time: String,
    pub update_time: String,
}

#[derive(InputObject)]
pub struct CreateProductADInput {
    pub product_id: String,
    pub cover_addr: String,
}

impl From< Model> for ProductADObject {
    fn from(model: Model) -> Self {
        ProductADObject {
            id: model.id.to_string(),
            product_id: model.product_id.to_string(),
            cover_addr: model.cover_addr,
            create_time: model.create_time.format("%Y-%m-%d %H:%M:%S").to_string(),
            update_time: model.update_time.format("%Y-%m-%d %H:%M:%S").to_string(),
        }
    }
}

#[derive(Default)]
pub struct ProductADQuery;

#[Object]
impl ProductADQuery {
    async fn advertising_list(
        &self,
        ctx: &Context<'_>,
    ) -> Result<Vec<ProductADObject>> {
        let db = ctx.data::<DatabaseConnection>()?;
        let conn = ctx.data::<MultiplexedConnection>()?;


        get_advertising_list(db, conn).await
    }
}

#[derive(Default)]
pub struct ProductADMutation;

#[Object]
impl ProductADMutation {

    #[graphql(guard = "AuthGuard(\"product:ad:delete\")")]
    async fn delete_advertising(
        &self,
        ctx: &Context<'_>,
        id: String,
    ) -> Result<bool> {
        let db = ctx.data::<DatabaseConnection>()?;
        let conn = ctx.data::<MultiplexedConnection>()?;
        delete_advertising(db, conn, id).await
    }

    #[graphql(guard = "AuthGuard(\"product:ad:create\")")]
    async fn create_advertising(
        &self,
        ctx: &Context<'_>,
        input: CreateProductADInput,
    ) -> Result<ProductADObject> {
        let db = ctx.data::<DatabaseConnection>()?;
        let conn = ctx.data::<MultiplexedConnection>()?;
        create_advertising(db, conn, input).await
    }
}